package com.athena.crm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.athena.common.core.domain.entity.SysDept;
import com.athena.common.core.domain.entity.SysUser;
import com.athena.common.core.domain.model.LoginUser;
import com.athena.common.helper.DataBaseHelper;
import com.athena.common.helper.LoginHelper;
import com.athena.common.utils.StreamUtils;
import com.athena.common.utils.StringUtils;
import com.athena.common.core.page.TableDataInfo;
import com.athena.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.athena.crm.constant.CommonConstant;
import com.athena.crm.domain.*;
import com.athena.crm.domain.bo.CrmClueBo;
import com.athena.crm.domain.bo.TUnlockRecordBo;
import com.athena.crm.domain.vo.CrmClueVo;
import com.athena.crm.domain.vo.CrmCustomerVo;
import com.athena.crm.mapper.CrmClueFollrecordsMapper;
import com.athena.crm.mapper.CrmClueMapper;
import com.athena.crm.service.ICrmClueService;
import com.athena.system.mapper.SysDeptMapper;
import com.athena.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * CRM线索Service业务层处理
 *
 * @author ruoyi
 * @date 2023-07-02
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class CrmClueServiceImpl implements ICrmClueService {

    private final CrmClueMapper baseMapper;

    private final SysDeptMapper deptMapper;

    private final SysUserMapper userMapper;

    private final CrmClueFollrecordsMapper crmClueFollrecordsMapper;

    private static Map<String, SysUser> userAllMap;
    /**
     * 查询CRM线索
     */
    @Override
    public CrmClueVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询CRM线索列表
     */
    @Override
    public TableDataInfo<CrmClueVo> queryPageList(LoginUser loginUser, CrmClueBo bo, PageQuery pageQuery) {
        Map<String, SysUser> userMap = getUserMap();
        if ("my".equals(bo.getType())) {
            bo.setHead(LoginHelper.getLoginUser().getUsername());
            bo.setClueStatus("线索");
            bo.setIsDeleted("0");
        }
        if ("customer".equals(bo.getType())) {
            bo.setClueStatus("已转客户");
            bo.setHead(LoginHelper.getLoginUser().getUsername());
            bo.setIsDeleted("1");
        }
        if ("all".equals(bo.getType())) {
            bo.setClueStatus("线索");
            bo.setIsDeleted("0");
        }
        String searchField = "id, name, phone, follow_status as followStatus, clues_sources as cluesSources, head, dept_id as deptId, dept_name as deptName, former_head as formerHead, former_dept_id as formerDeptId, latest_follow_records as latestFollowRecords, reality_follow_records as realityFollowRecords, DATEDIFF(NOW(), reality_follow_records)  as notFollowDays, next_follow_time as nextFollowTime, channel, transfer_customer_time as transferCustomerTime, last_call_time as lastCallTime, create_by as createBy, create_time as createTime, update_by updateBy, update_time as updateTime";
        LambdaQueryWrapper<CrmClue> queryWrapper = new QueryWrapper<CrmClue>()
            .select(searchField).lambda();
        LambdaQueryWrapper<CrmClue> lqw = buildNewQueryWrapper(queryWrapper, loginUser, bo);
        lqw.orderByDesc(CrmClue::getUpdateTime);
        Page<CrmClueVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        if (!CollectionUtils.isEmpty(result.getRecords())) {
            for (CrmClueVo crmClueVo : result.getRecords()) {
                SysUser sysUser = userMap.get(crmClueVo.getHead());
                if (sysUser != null) {
                    crmClueVo.setHead(sysUser.getNickName() + "(" + sysUser.getUserName() + ")");
                }
            }
        }
        return TableDataInfo.build(result);
    }

    @Override
    public Map<String, SysUser> getUserMap() {
        Map<String, SysUser> userMap = userAllMap;
        if (userMap == null || userMap.isEmpty()) {
            List<SysUser> sysUsers = userMapper.selectList();
            userMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserName, sysUser -> sysUser));
        }
        return userMap;
    }

    /**
     * 查询CRM线索列表
     */
    @Override
    public List<CrmClueVo> queryList(LoginUser loginUser, CrmClueBo bo) {
        LambdaQueryWrapper<CrmClue> lqw = buildQueryWrapper(loginUser, bo);
        lqw.orderByDesc(CrmClue::getUpdateTime);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<CrmClue> buildNewQueryWrapper(LambdaQueryWrapper<CrmClue> lqw, LoginUser loginUser, CrmClueBo bo) {
        Map<String, Object> params = bo.getParams();
        lqw.like(StringUtils.isNotBlank(bo.getName()), CrmClue::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getPhone()), CrmClue::getPhone, bo.getPhone());
        if (StringUtils.isNotBlank(bo.getIsDeleted())) {
            lqw.eq(StringUtils.isNotBlank(bo.getIsDeleted()), CrmClue::getIsDeleted, bo.getIsDeleted());
        }
        if (StringUtils.isNotBlank(bo.getClueStatus())) {
            lqw.eq(StringUtils.isNotBlank(bo.getClueStatus()), CrmClue::getClueStatus, bo.getClueStatus());
        }
        if (StringUtils.isNotBlank(bo.getFollowStatus())) {
            String[] followStatus = bo.getFollowStatus().split(",");
            lqw.in(StringUtils.isNotBlank(bo.getFollowStatus()), CrmClue::getFollowStatus, followStatus);
        }
        if (StringUtils.isNotBlank(bo.getCluesSources())) {
            String[] cluesSources = bo.getCluesSources().split(",");
            lqw.in(StringUtils.isNotBlank(bo.getCluesSources()), CrmClue::getCluesSources, cluesSources);
        }
        if (StringUtils.isNotBlank(bo.getChannel()) && !"无".equals(bo.getChannel())) {
            String[] channels = bo.getChannel().split(",");
            lqw.in(StringUtils.isNotBlank(bo.getChannel()), CrmClue::getChannel, channels);
        }
        if (StringUtils.isNotBlank(bo.getChannel()) && "无".equals(bo.getChannel())) {
            lqw.isNull(CrmClue::getChannel);
        }
        if (bo.getHeads() != null) {
            lqw.in(CrmClue::getHead, bo.getHeads());
        } else {
            if (!"all".equals(bo.getType())) {
                lqw.eq(CrmClue::getHead, bo.getHead());
            }
        }
        lqw.eq(StringUtils.isNotBlank(bo.getFormerHead()), CrmClue::getFormerHead, bo.getFormerHead());
        if(bo.getFormerDeptId() != null) {
            lqw.eq(StringUtils.isNotBlank(bo.getFormerDeptId().toString()), CrmClue::getFormerDeptId, bo.getFormerDeptId());
        }
        lqw.eq(bo.getLatestFollowRecords() != null, CrmClue::getLatestFollowRecords, bo.getLatestFollowRecords());
        if (!CollectionUtils.isEmpty(bo.getRealityFollowRecordsSearch())) {
            lqw.between( CrmClue::getRealityFollowRecords, bo.getRealityFollowRecordsSearch().get(0), bo.getRealityFollowRecordsSearch().get(1));
        }
        lqw.eq(bo.getNotFollowDays() != null, CrmClue::getNotFollowDays, bo.getNotFollowDays());
        lqw.eq(bo.getNextFollowTime() != null, CrmClue::getNextFollowTime, bo.getNextFollowTime());
        lqw.eq(bo.getTransferCustomerTime() != null, CrmClue::getTransferCustomerTime, bo.getTransferCustomerTime());
        if (!CollectionUtils.isEmpty(bo.getLastCallTime())) {
            lqw.between( CrmClue::getLastCallTime, bo.getLastCallTime().get(0), bo.getLastCallTime().get(1));
        }
        if (bo.getDeptIds() != null) {
            lqw.in(CrmClue::getDeptId, bo.getDeptIds());
        } else {
            lqw.and(ObjectUtil.isNotNull(loginUser.getDeptId()), w -> {
                List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
                    .select(SysDept::getDeptId)
                    .apply(DataBaseHelper.findInSet(loginUser.getDeptId(), "ancestors")));
                List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
                ids.add(loginUser.getDeptId());
                w.in(CrmClue::getDeptId, ids);
            });
        }
        return lqw;
    }

    private LambdaQueryWrapper<CrmClue> buildQueryWrapper(LoginUser loginUser, CrmClueBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<CrmClue> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getName()), CrmClue::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getPhone()), CrmClue::getPhone, bo.getPhone());
        if (StringUtils.isNotBlank(bo.getFollowStatus())) {
            String[] followStatus = bo.getFollowStatus().split(",");
            lqw.in(StringUtils.isNotBlank(bo.getFollowStatus()), CrmClue::getFollowStatus, followStatus);
        }
        lqw.eq(StringUtils.isNotBlank(bo.getCluesSources()), CrmClue::getCluesSources, bo.getCluesSources());
        lqw.eq(StringUtils.isNotBlank(bo.getHead()), CrmClue::getHead, bo.getHead());
        lqw.eq(StringUtils.isNotBlank(bo.getDeptId()), CrmClue::getDeptId, bo.getDeptId());
        lqw.eq(StringUtils.isNotBlank(bo.getFormerHead()), CrmClue::getFormerHead, bo.getFormerHead());
        if(bo.getFormerDeptId() != null) {
            lqw.eq(StringUtils.isNotBlank(bo.getFormerDeptId().toString()), CrmClue::getFormerDeptId, bo.getFormerDeptId());
        }
        lqw.eq(bo.getLatestFollowRecords() != null, CrmClue::getLatestFollowRecords, bo.getLatestFollowRecords());
        lqw.eq(bo.getRealityFollowRecords() != null, CrmClue::getRealityFollowRecords, bo.getRealityFollowRecords());
        lqw.eq(bo.getNotFollowDays() != null, CrmClue::getNotFollowDays, bo.getNotFollowDays());
        lqw.eq(bo.getNextFollowTime() != null, CrmClue::getNextFollowTime, bo.getNextFollowTime());
        lqw.eq(StringUtils.isNotBlank(bo.getChannel()), CrmClue::getChannel, bo.getChannel());
        lqw.eq(bo.getTransferCustomerTime() != null, CrmClue::getTransferCustomerTime, bo.getTransferCustomerTime());
        lqw.eq(bo.getLastCallTime() != null, CrmClue::getLastCallTime, bo.getLastCallTime());
        lqw.and(ObjectUtil.isNotNull(loginUser.getDeptId()), w -> {
            List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>()
                .select(SysDept::getDeptId)
                .apply(DataBaseHelper.findInSet(loginUser.getDeptId(), "ancestors")));
            List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
            ids.add(loginUser.getDeptId());
            w.in(CrmClue::getDeptId, ids);
        });
        return lqw;
    }

    /**
     * 新增CRM线索
     */
    @Override
    public Boolean insertByBo(CrmClueBo bo) {
        CrmClue add = BeanUtil.toBean(bo, CrmClue.class);
        add.setUpdateBy("1");
        add.setFollowStatus("未处理");
        add.setClueStatus("线索");
        add.setDeptId(LoginHelper.getDeptId());
        add.setDeptName(LoginHelper.getLoginUser().getDeptName());
        add.setIsDeleted("0");
        add.setRealityFollowRecords(new Date());
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改CRM线索
     */
    @Override
    public Boolean updateByBo(CrmClueBo bo) {
        CrmClue update = BeanUtil.toBean(bo, CrmClue.class);
        validEntityBeforeSave(update);
        if(baseMapper.updateById(update) > 0) {
            CrmClueFollrecords crmClueFollrecords = new CrmClueFollrecords();
            crmClueFollrecords.setClueId(update.getId() + "");
            crmClueFollrecords.setFollowUser(LoginHelper.getLoginUser().getUsername());
            crmClueFollrecords.setFollowContent("更新线索[" + update.getName() + "]基本信息");
            crmClueFollrecords.setFlowType(CommonConstant.FOLLOW_TYPE_OPERATE_LOG);
            crmClueFollrecordsMapper.insert(crmClueFollrecords);
        }
        return true;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(CrmClue entity){
        //TODO 做一些数据校验,如唯一约束
        SysDept sysDept = deptMapper.selectById(entity.getDeptId());
        if (sysDept != null) {
            entity.setDeptName(sysDept.getDeptName());
        }
    }

    /**
     * 批量删除CRM线索
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<CrmClue> batchInsertByBo(List<CrmClue> crmClues) {
        boolean flag = baseMapper.insertBatch(crmClues);
        return crmClues;
    }
}
